<template>
  <div>
    <h1>数据类型</h1>
    <!-- 
      ts的数据类型 
          string、number、boolean、undefined、null、object、array、any、unknown、枚举、元组、类型联合 
    -->
    <!-- 
      事实证明：
        1、toRaw() 可以将proxy 对象，转换为普通对象。 即响应式转换为非响应式。
            这里的proxy对象，指向两个。(1) reactive()包裹的对象； (2) ref()包裹的对象 .value 也是proxy对象。
        2、markRaw()  标记响应式对象的属性，不为响应式数据。

        一和多的区别，toRaw 将proxy对象转换成普通对象，即 所有属性都不是响应式的了；
                    markRaw 将proxy对象中的某一个属性，变成了非响应式。
     -->
    <h1>reactive</h1>
    <h1>{{ obj.name }}</h1>
    <h1>{{ obj.age }}</h1>
    <input type="text" v-model="obj.name"><br>
    <input type="text" v-model="obj.age"><br>
    <h1>toRaw</h1>
    <h1>{{ objToRaw.name }}</h1>
    <h1>{{ objToRaw.age }}</h1>
    <input type="text" v-model="objToRaw.name"><br>
    <input type="text" v-model="objToRaw.age"><br>
    <h1>objRef</h1>
    <h1>{{ objr.name }}</h1>
    <h1>{{ objr.age }}</h1>
    <input type="text" v-model="objr.name"><br>
    <input type="text" v-model="objr.age"><br>
    <h1>objRefToRaw</h1>
    <h1>{{ objRefToRaw.name }}</h1>
    <h1>{{ objRefToRaw.age }}</h1>
    <input type="text" v-model="objRefToRaw.name"><br>
    <input type="text" v-model="objRefToRaw.age"><br>
    <button @click="look">查看 obj 与 objToRaw</button><br>
    <h1>{{obj}}</h1>
    <button @click="objAddArr">objAddArr</button>

  </div>
</template>

<script lang="ts">
import { defineComponent, reactive, toRaw, ref, markRaw } from 'vue'

export default defineComponent({
  setup() {
    //一、toRaw  将一个响应式的proxy对象，转换成非响应式的普通对象。

    //创建一个响应式对象
    const obj = reactive<any>({
      name: 'tom',
      age: 20
    })
    //使用ref 使引用数据变成响应式对象
    const objr = ref({
      name: 'tom',
      age: 20
    })

    //使用toRaw 将响应式对象 变成普通对象
    const objToRaw = toRaw(obj);
    const objRefToRaw = toRaw(objr.value)

    //查看 obj 与 objToRaw
    function look() {
      console.log(obj);//Proxy{name:'tom', age:20}
      console.log(objToRaw);//{name: 'tom', age: 20}
      console.log(objr.value);//Proxy{name: 'tom', age: 20}
      console.log(objRefToRaw);//{name: 'tom', age: 20}
    }

    //二、markRow
    //创建一个函数  目的是给对象 添加一个数组
    function objAddArr() {
      const arrs = [1, 2];
      // obj.arr = arr;  报错 是因为我们写obj时，reactive()没设置类型声明，则类型推断 obj中只有name和age两个属性，我们通过泛型设置一下类型声明就可以了      类型推断 将声明变量和赋值 搞一块去了 类似于字面量  类型推断的类型声明是字面量
      // obj.arr = arr;  obj添加的arr属性，能呈现响应式效果
      //因为obj 是proxy对象，在它上面添加的属性arr 也能呈现出响应式效果 

      //需求：不想让新添加的属性，为响应式的。
      obj.arrs = markRaw(arrs)//arrs 则不会响应
      
      //设置延时定时器
      setTimeout(() => {
        obj.arrs[0] += 1;
       
      }, 500)
      
    }
    return {
      obj,
      objToRaw,
      look,
      objr,
      objRefToRaw,
      objAddArr
    }
  }
})
</script>

<style scoped>

</style>